#include "remainder.h"
#include "gcd.h"
#include "stein_gcd.h"
#include "quotient_remainder.h"

#include <iostream>

void test_stein_gcd();
void test_quotient_remainder();
void test_remainder();
void test_gcd();

int main()
{
	test_remainder();
	test_gcd();

	test_stein_gcd();
	test_quotient_remainder();
}

void test_remainder()
{
	int a = 44, b = 5;
	int rem = slow_remainder(a,b);
	int quo = slow_quotient(a,b);
	std::cout << a << " % " << b << " = " << rem << std::endl;
	std::cout << a << " / " << b << " = "<< quo << std::endl;

	rem = remainder_nonnegative(44, 5);
	std::cout << a << " % " << b << " = " << rem << std::endl;

	rem = remainder_nonnegative_iterative(44, 5);
	std::cout << a << " % " << b << " = " << rem << std::endl;

	rem = remainder(a,b,slow_remainder<int>);
	std::cout << a << " % " << b << " = " << rem << std::endl;

	a = -44, b = 5;
	rem = remainder(a,b,&slow_remainder<int>);
	std::cout << a << " % " << b << " = " << rem << std::endl;
}

void test_gcd()
{
	int a,b,gcd;
	a = 48, b = 36;
	gcd = subtractive_gcd_nonzero(a,b);
	std::cout << "gcd(" << a << "," << b << ") = " << gcd << std::endl;

	a = 48, b = 18;
	gcd = subtractive_gcd_nonzero(a,b);
	std::cout << "gcd(" << a << "," << b << ") = " << gcd << std::endl;

	a = 0, b = 36;
	gcd = subtractive_gcd(a,b);
	std::cout << "gcd(" << a << "," << b << ") = " << gcd << std::endl;

	a = 48, b = 0;
	gcd = subtractive_gcd(a,b);
	std::cout << "gcd(" << a << "," << b << ") = " << gcd << std::endl;

	a = 48, b = 36;
	gcd = fast_subtractive_gcd(a,b);
	std::cout << "gcd(" << a << "," << b << ") = " << gcd << std::endl;

	a = 48, b = 18;
	gcd = fast_subtractive_gcd(a,b);
	std::cout << "gcd(" << a << "," << b << ") = " << gcd << std::endl;
}

void test_stein_gcd()
{
	int a,b,gcd;
	a = 48, b = 36;
	gcd = stein_gcd_recursive(a,b);
	std::cout << "gcd(" << a << "," << b << ") = " << gcd << std::endl;

	a = 48, b = 18;
	gcd = stein_gcd_recursive(a,b);
	std::cout << "gcd(" << a << "," << b << ") = " << gcd << std::endl;
}

void test_quotient_remainder()
{
	int a,b;
	a = 7, b = 3;
	std::pair<int,int> q;
	
	q = quotient_remainder_nonnegative_recursive<int,int>(a,b);
	std::cout << a << " / " << b << " = "<< q.first << " mod " << q.second << std::endl;

	q = quotient_remainder_nonnegative_iterative<int,int>(a,b);
	std::cout << a << " / " << b << " = "<< q.first << " mod " << q.second << std::endl;

	q = quotient_remainder<std::pair<int,int> (*)(int,int),int,int>(a,b,quotient_remainder_nonnegative_recursive<int,int>);
	std::cout << a << " / " << b << " = "<< q.first << " mod " << q.second << std::endl;

	a = -44, b = 5;
	q = quotient_remainder<std::pair<int,int> (*)(int,int),int,int>(a,b,quotient_remainder_nonnegative_recursive<int,int>);
	std::cout << a << " / " << b << " = "<< q.first << " mod " << q.second << std::endl;
}
/*
44 % 5 = 4
44 / 5 = 8
44 % 5 = 4
44 % 5 = 4
44 % 5 = 4
-44 % 5 = 1
gcd(48,36) = 12
gcd(48,18) = 6
gcd(0,36) = 36
gcd(48,0) = 48
gcd(48,36) = 12
gcd(48,18) = 6
gcd(48,36) = 12
gcd(48,18) = 6
7 / 3 = 2 mod 1
7 / 3 = 2 mod 1
7 / 3 = 2 mod 1
-44 / 5 = -9 mod 1
*/